<?php

namespace App\Model\Common;

use App\Model\CrudModel;
use App\Pool\Redis\DefaultPool;
use App\Utils\Helper;
use Hyperf\Di\Annotation\Inject;

/**
 * @property int $id
 * @property int $deleted_at 删除标识
 * @property int $pid 上级id
 * @property int $sort
 * @property string $code
 * @property string $name
 * @property string $cover
 * @property int $created_at
 * @property int $updated_at
 * </pre>
 */
class CategoryModel extends CrudModel
{

    // 所有的api
    protected ?string $table = 'category';

    protected array $adminPageListField = [
        'id','code','name','pid','sort','cover',
    ];

    #[Inject]
    protected DefaultPool $defaultPool;

    // 缓存tree数据的key
    protected string $cacheKey = '_category_';

    public function addOne(array $data)
    {
        return $this->normalAddOne([
            'pid' => intval($data['pid']),
            'sort' => intval($data['sort']),
            'code' => trim($data['code'] ?? ''),
            'name' => trim($data['name']),
            'cover' => trim($data['cover'] ?? ''),
        ]);
    }

    public function updateById($id, array $data)
    {
        return $this->buildQuery(['id'=>$id,])->update([
            'pid' => intval($data['pid']),
            'sort' => intval($data['sort']),
            'code' => trim($data['code'] ?? ''),
            'name' => trim($data['name']),
            'cover' => trim($data['cover'] ?? ''),
            'updated_at' => time(),
        ]);
    }

    public function tree()
    {
        $tree = $this->readTreeCache();
        if ($tree){
            return $tree;
        }
        return $this->refreshTree();
    }

    protected function writeTreeCache($tree)
    {
        $cacheKey = $this->cacheKey;
        $treeWriteCacheData = [];
        foreach ($tree as $item2){
            if (is_array($item2)){
                $treeWriteCacheData[$item2['code']] = json_encode($item2);
            }
        }
        $this->defaultPool->hMSet($cacheKey, $treeWriteCacheData);
    }

    /**
     * @return array
     * @throws \RedisException
     */
    protected function readTreeCache()
    {
        $cacheKey = $this->cacheKey;
        $tree = $this->defaultPool->hGetAll($cacheKey);
        if ($tree){
            foreach ($tree as &$item){
                $item = json_decode($item,true);
            }
        }
        return $tree;
    }

    public function refreshTree()
    {
        $tree = $this->treeFromDb();
        // 酌情使用
        $this->defaultPool->del($this->cacheKey);

        $this->writeTreeCache($tree);
        return $tree;
    }

    public function treeFromDb()
    {
        $lists = $this->getAll([], $this->adminPageListField);
        if ($lists->isEmpty()){
            return [];
        }
        return Helper::generateTree($lists->toArray());
    }
}